import { action, observable } from "mobx";
import API from '../../../apis/task';
import CellType from '../../excel/celltypes';
import Function from '../../excel/function'
import ExcelAPI from '../../../apis/excel';
import TaskAPI from '../../../apis/task';
import FunAPI from '../../../apis/formula';
import getCellName from '../../../utils/getCellName';
import { WeaTools } from 'ecCom'
import { each } from 'lodash';
import { message } from 'antd';
import route from "../../../constants/route";
import { register, removeAllSpan, sortRecords } from "./command";
import MenuActions from './menu/action';
import * as Events from './event';
import { WeaLocaleProvider } from "ecCom";
import CustomFunction from "../../excel/function/CustomFunction";
import ComponentStore from "../../form/ComponentStore";
const getLabel = WeaLocaleProvider.getLabel;
export const styleNames = ["backColor", "foreColor", "hAlign", "vAlign",
    "font", "formatter", "borderLeft", "borderTop", "borderRight",
    "borderBottom", "diagonalDown", "diagonalUp", "locked", "textIndent",
    "wordWrap", "shrinkToFit", "backgroundImage", "backgroundImageLayout",
    "tabStop", "textDecoration", "imeMode", "watermark", "cellPadding",
    "labelOptions", "quotePrefix", "isVerticalText"];

export default class TaskViewExcelStore {
    @observable title = '';
    @observable activeCellName = '';
    @observable isInit = false;
    @observable loading = false;
    @observable showDetailDelete = false;
    @observable customFuns;
    @observable oldPage;
    @observable excelStore;
    @observable uploadtitle = getLabel('502835', '导入数据');
    @observable visible = false;
    @observable needCheck = true;
    deletedRows = {};
    func = [];

    @observable loadingPage = true;
    @observable isRight = false;
    @observable cuscode = '';
    @observable rowControl = {};
    @observable autoSaveDatas = [];
    @observable firstSet = false;
    @observable autoSaveDatasvisible = false;
    @observable canSubmit = false;
    @observable requiredCellBoderStyle = {};
    @observable requiredCellName = "";
    @observable fieldAssignList = {};

    @observable detailDataRow = [];

    constructor() {
        each(MenuActions, (value, key) => {
            this[key] = action(value.bind(this));
        });
        each(Events, (value, key) => {
            this[key] = action(value.bind(this));
        });
    }
    refresh = () => {
        setTimeout(() => {
            this.workbook.refresh();
        }, 10);
    }
    @action loadWorkbook = () => {
        this.isInit = true;
    }
    @action initWorkbook = (workbook, readonly) => {
        this.workbook = workbook;
        window.workbookInstance = workbook;
        this.readonly = readonly;
    }
    @action init = (params) => {

        this.updateJsonInstance = window.updateJson = {};
        
        this.func = [];
        this.params = params;
        if (this.intervalAutoSave) {
            clearInterval(this.intervalAutoSave);
        }
        this.loading = true;
        API.showDetail({ nodeid: this.params.nodeid, pageid: this.params.pageid }).then(result => { //
            this.loadingPage = false;
            if (result.isShowDetail) {
                this.isRight = true;
                Promise.all([
                    API.excel2(this.params),
                    FunAPI.loadFormula(this.params.pageid)
                ]).then(([page, formulas]) => {
                    this.setViewInfo(page);
                    this.customFuns = formulas;
                })
                //API.excel(this.params).then(this.setViewInfo);
            }
        });
    }

    @action setViewInfo = (view) => {
        const { page = {}, autoSaveType } = view || {};
        this.title = page.name;
        //this.canSubmit = view.canSubmit;
        this.loading = false;
        this.showPage(page);
        
        //dataTable改造 关闭自动保存

        // 有自动保存设置、且可编辑
        // if (autoSaveType == '1' && this.canSubmit && this.notAutoSave != '1') {
        //     this.autoSaveDatas = view.autoSaveDatas || [];
        //     if (view.autoSaveDatas && !this.firstSet) {
        //         this.firstSet = true;
        //         this.autoSaveDatasvisible = true;
        //     }
        //     this.autoSave(view);
        // }
    }


    @action
    changeSelectTypeValue = () => {
        this.workbook.suspendPaint();
        this.workbook.sheets.forEach(sheet => {
            // 明细表
            sheet.tables.all().forEach(table => {
                const bindingPath = table.bindingPath();
                if (bindingPath) {
                    const { col, colCount, row, rowCount } = table.dataRange();
                    for (let i = 0; i < colCount; i++) {
                        const cell = sheet.getCell(Number(row), Number(col + i));
                        const cellType = cell.cellType();

                        if (cellType && cellType.typeName == 'WeaSelectCellType' && cellType.fieldType) {
                            for (let j = 0; j < rowCount; j++) {
                                const c = sheet.getCell(Number(row + j), Number(col + i));
                                const value = c.value();
                                if (value) {
                                    
                                    c.value('-999');
                                    c.value(value);
                                } else {
                                    c.value('-999');
                                    c.value(value);
                                }
                            }

                        }
                    }
                }

            });

            const { data } = sheet.toJSON();
            if (data) {
                const { dataTable } = data;
                if (dataTable) {
                    each(dataTable, (o, rowIndex) => {
                        each(o, (obj, colIndex) => {
                            const bindingPath = sheet.getBindingPath(rowIndex, colIndex);
                            if (bindingPath) {

                                const cell = sheet.getCell(Number(rowIndex), Number(colIndex));
                                const cellType = cell.cellType();
                                if (cellType && cellType.typeName == 'WeaSelectCellType' && cellType.fieldType) {
                                    const value = cell.value();
                                    if (value) {
                                        cell.value('-999');
                                        cell.value(value);
                                    } else {
                                        cell.value('-999');
                                        cell.value(value);
                                    }
                                }
                            }

                        });
                    });

                }
            }
        });
        this.workbook.resumePaint();
    }


    autoSave = (view) => {
        const { autoSaveType, saveTime = 0, saveTimeType = 0 } = view || {};

        let intervalTime = 0;
        if (saveTime > 0) {
            if (saveTimeType == 0) {
                intervalTime = saveTime * 60 * 1000;
            } else {
                intervalTime = saveTime * 60 * 60 * 1000;
            }
            this.intervalAutoSave = setInterval(() => {
                this.autoSaveData();
            }, intervalTime)

        }
    }

    autoSaveData = () => {
        if (!this.doBefore()) {
            return;

        }
        const source = this.dataSourceInstance.getSource();
        TaskAPI.autoSaveData({
            ...this.params,
            datas: JSON.stringify(source),
            deletedRows: JSON.stringify(this.deletedRows),
        }).then((ds) => {
            if (ds) {
                this.autoSaveDatas = ds;
                if (!this.firstSet) {
                    this.firstSet = true;
                    this.autoSaveDatasvisible = true;
                }

                message.success("自动" + getLabel('502231', '保存成功'));
            }
        });
    }

    getPageJSON = (page, readonly) => {
        if (page.pageType === 0) {
            this.oldPage = page;
            const json = JSON.parse(page.json);
            const { sheets } = json;
            each(sheets, (sheet, name) => {
                const { data } = sheet;
                const { dataTable } = data;
                each(dataTable, (rowData, row) => {
                    each(rowData, (cellData, col) => {
                        const { style = {} } = cellData;
                        const { cellType } = style;
                        if (cellType) {
                            delete style.backgroundImage;
                            delete style.backgroundImageLayout;
                            delete style.textIndent;
                            const { fieldType } = cellType;
                            if (fieldType) {
                                const [htmltype, type] = fieldType;
                                style.locked = this.readonly;
                                if (!cellType.viewAttr) {
                                    cellType.viewAttr = 2;
                                }
                                if (this.readonly) {
                                    cellType.viewAttr = 1;
                                }
                                if (htmltype === 'select') {
                                    cellType.typeName = 'WeaSelectCellType';
                                } else if (htmltype === 'check') {
                                    cellType.typeName = 'WeaCheckboxCellType';
                                } else if (htmltype === 'browser') {
                                    const { value = '' } = type || {};
                                    if (value === '2' || value === '290') {
                                        cellType.typeName = 'WeaDatePickerCellType';
                                    } else if (value === '258' || value === '2222' || value === '58' || value === '263') {
                                        cellType.typeName = 'WeaCityPickerCellType';
                                    } else if (value === '19') {
                                        cellType.typeName = 'WeaTimePickerCellType';
                                    } else {
                                        cellType.typeName = 'WeaBrowserCellType';
                                    }
                                } else {
                                    cellType.typeName = 'WeaInputCellType';
                                    style.formatter = "@";
                                }
                            } else if (cellType.typeName === 'NoFieldCellType') {
                                cellType.display = true;
                            }
                        }
                    });
                });

            });
            return json;
        } else {
            return page.json;
        }
    }

    showPage = (page,flag) => {
        if (!this.workbook) {
            setTimeout(() => {
                this.showPage(page);
            }, 50);
            return;
        }

        const json = this.getPageJSON(page);
        console.log("json",json)

        
        const dataSource = window.dataSourceInstance = this.dataSourceInstance = new GC.Spread.Sheets.Bindings.CellBindingSource(page.dataSource);
        console.log("dataSource",dataSource)

        const WeaInputCellType = window.WeaInputCellType = CellType('WeaInputCellType');
        const WeaCheckboxCellType = window.WeaCheckboxCellType = CellType('WeaCheckboxCellType');
        const WeaBrowserCellType = window.WeaBrowserCellType = CellType('WeaBrowserCellType');
        const WeaSelectCellType = window.WeaSelectCellType = CellType('WeaSelectCellType');
        const NoFieldCellType = window.NoFieldCellType = CellType('NoFieldCellType');
        const WeaCityPickerCellType = window.WeaCityPickerCellType = CellType('WeaCityPickerCellType');
        if (typeof (page.rowControl) != 'undefined') {
            this.rowControl = JSON.parse(page.rowControl);
        }

        if (typeof (page.fieldAssignList) != 'undefined') {
            this.fieldAssignList = JSON.parse(page.fieldAssignList);
        }
        let initData = [];
        if (page.initData) {
            initData = JSON.parse(page.initData);
        }
        window.WeaDatePickerCellType = CellType('WeaDatePickerCellType');
        window.WeaTimePickerCellType = CellType('WeaTimePickerCellType');
        window.DetailIndexType = CellType('DetailIndexType');
        const FieldCellType = CellType('FieldCellType');
        window.FieldCellType = FieldCellType;
        const afters = this.loadFormula();
        const cuscode = page.cuscode ? WeaTools.Base64.decode(page.cuscode) : "";
        this.workbook.suspendPaint();
        this.workbook.fromJSON(json, false);

        this.func = [];
        this.clipboardRanges = [];
        if (page.pageType === 0) { // 填报页
            this.workbook.getHost().addEventListener('click', this.clickAnyWhere);
            this.workbook.getHost().addEventListener('mousemove', this.mouseOverAnyWhere);
            this.workbook.bind(GC.Spread.Sheets.Events.DragFillBlock, this.dragFillBlock);
            this.workbook.bind(GC.Spread.Sheets.Events.CellClick, this.cellClick);
            this.workbook.bind(GC.Spread.Sheets.Events.EnterCell, this.enterCell);
            this.workbook.bind(GC.Spread.Sheets.Events.EditStarting, this.editStarting);
            this.workbook.bind(GC.Spread.Sheets.Events.ActiveSheetChanged, this.activeSheetChange);
            this.workbook.bind(GC.Spread.Sheets.Events.EditEnded, this.editEnded);
            this.workbook.bind(GC.Spread.Sheets.Events.ClipboardChanged, this.ClipboardChanged);

            this.workbook.bind(GC.Spread.Sheets.Events.TopRowChanged, this.topRowChanged);

             //初始化加载数据源
            if (initData && initData.length > 0) {
                initData.forEach((r) => {
                    if (r.fieldtype == "mainfield") {
                        const mainValue = dataSource.getValue(r.field);
                        if (!mainValue || mainValue == "") {
                            dataSource.setValue(r.field, r.value);
                        }
                    } else if (r.fieldtype == "detailfield") {
                        const field = r.field;
                        if (field) {
                            const paths = field.split('.');
                            let bindingPath = "";
                            let dfield = "";
                            if (paths.length >= 3) {
                                bindingPath = paths[0] + '.' + paths[1];
                                dfield = paths[2];
                            }
                            const records = dataSource.getValue(bindingPath);
                            const rowCount = records.length;
                            const dataCount = r.value.length;
                            const newRecords = [];
                            if (rowCount <= dataCount) {
                                r.value.forEach((data, dataIndex) => {
                                    if (dataIndex < rowCount) {
                                        const { [dfield]: oldvalue } = records[dataIndex];
                                        if (oldvalue && oldvalue != "") {
                                            newRecords.push({ ...records[dataIndex] });
                                        } else {
                                            newRecords.push({ ...records[dataIndex], [dfield]: data });
                                        }
                                    } else {
                                        newRecords.push({ [dfield]: data, detail_index: dataIndex + 1 });
                                    }
                                });
                            } else {
                                records.forEach((record, recordIndex) => {
                                    if (recordIndex < dataCount) {
                                        const { [dfield]: oldvalue } = record;
                                        if (oldvalue && oldvalue != "") {
                                            newRecords.push({ ...record });
                                        } else {
                                            newRecords.push({ ...record, [dfield]: r.value[recordIndex] });
                                        }

                                    } else {
                                        newRecords.push({ ...record });
                                    }
                                });
                            }
                            dataSource.setValue(bindingPath, newRecords);
                        }
                    }
                });
            }

            const { sheets = {} } = json;
            this.detailDataRow = [];
            this.workbook.sheets.forEach(sheet => {
                sheet.bind(GC.Spread.Sheets.Events.CellChanged, this.cellChanged)
                const sheetName = sheet.name();
                const sheetObj = sheets[sheetName] || {};
                const { tables = [], data: { dataTable = {} } = {} } = sheetObj;
                window.dataTableInstance = dataTable
                sheet.tables.all().forEach((table, tableIndex) => {
                    table.filterButtonVisible(false);
                    table.autoGenerateColumns(false);
                    if (tables.length > tableIndex) {
                        const tableObj = tables[tableIndex] || {};
                        const { name, row, columns = [] } = tableObj;
                        this.detailDataRow.push({
                            name: name,
                            dataRow: row+1+1
                        })
                        const tableColumns = [];
                        const { row: dataRow, col: dataCol } = table.dataRange();
                        const spanKeys = [];
                        columns.forEach((column, columnIndex) => {
                            const { style = {}, formula } = (dataTable[dataRow] || {})[dataCol + columnIndex] || {};
                            const { cellType = {} } = style;
                            if (cellType.combineSameCell) {
                                spanKeys.push({
                                    name: cellType.fieldName,
                                    index: columnIndex
                                });
                            }

                            if (cellType.typeName) {
                                const CellTypeClass = window[cellType.typeName];
                                if (CellTypeClass) {
                                    let cellTypeInstance = new CellTypeClass();
                                    cellTypeInstance.fromJSON(cellType);
                                    this.func.push({
                                        key: sheetName,
                                        action: () => {
                                            const { rowCount: oldRowCount = 0, row: oldRow = 0 } = table.oldDataRange || {};
                                            let startRow = oldRow + oldRowCount;
                                            const { row, col, rowCount } = table.dataRange();
                                            if (rowCount > oldRowCount) {
                                                if (cellType.typeName == 'WeaSelectCellType') {
                                                    startRow = (startRow === 0 ? row : startRow);
                                                    for (let i = 0; i < rowCount - oldRowCount; i++) {

                                                        cellTypeInstance = new CellTypeClass();
                                                        cellTypeInstance.fromJSON(cellType);
                                                        sheet.getCell(startRow + i, col + columnIndex).cellType(cellTypeInstance);
                                                    }
                                                } else {
                                                    sheet.getRange(startRow === 0 ? row : startRow, col + columnIndex, rowCount - oldRowCount, 1).cellType(cellTypeInstance);
                                                }

                                            }
                                        }
                                    });
                                }
                            }
                            const span = sheet.getSpan(dataRow, dataCol + columnIndex);
                            if (span && span.row === dataRow && span.col === dataCol + columnIndex) {
                                this.func.push({
                                    key: sheetName,
                                    action: () => {
                                        const { rowCount: oldRowCount = 0 } = table.oldDataRange || {};
                                        const { row, rowCount } = table.dataRange();
                                        if (rowCount > oldRowCount) {
                                            for (let spanIndex = 0; spanIndex < rowCount; spanIndex++) {
                                                sheet.addSpan(row + spanIndex, dataCol + columnIndex, span.rowCount, span.colCount);
                                            }
                                        }
                                    }
                                });
                            }
                            styleNames.forEach(styleName => {
                                if (style[styleName] !== void 0) {
                                    this.func.push({
                                        key: sheetName,
                                        action: () => {
                                            const { rowCount: oldRowCount = 0, row: oldRow = 0 } = table.oldDataRange || {};
                                            const startRow = oldRow + oldRowCount;
                                            const { row, col, rowCount } = table.dataRange();
                                            if (rowCount > oldRowCount) {
                                                sheet.getRange(startRow === 0 ? row : startRow, col + columnIndex, rowCount - oldRowCount, 1)
                                                    ._w(styleName, this.getStyleValue(style, styleName));
                                            }
                                        }
                                    });
                                }
                            });
                            this.func.push({
                                key: sheetName,
                                action: () => {
                                    const { rowCount: oldRowCount = 0, row: oldRow = 0 } = table.oldDataRange || {};
                                    const startRow = oldRow + oldRowCount;
                                    const { row, col, rowCount } = table.dataRange();
                                    if (rowCount > oldRowCount && formula) {
                                        table.setColumnDataFormula(columnIndex, `=${formula}`)
                                    }
                                    /* if (rowCount > oldRowCount && formula) {
                                        // console.log(formula)
                                        sheet.getRange(startRow === 0 ? row : startRow, col + columnIndex, rowCount - oldRowCount, 1).formula(`=${formula}`);
                                    } */
                                }
                            });
                            const tableCol = new GC.Spread.Sheets.Tables.TableColumn('' + columnIndex);
                            tableCol.name(column.name);
                            tableCol.dataField(column.dataField);
                            tableColumns.push(tableCol);
                        });

                        const bindpath = table.bindingPath();
                        const records = dataSource.getValue(bindpath) || [];
                        dataSource.setValue(bindpath, sortRecords(records, spanKeys))
                        if (spanKeys.length > 0) {
                            this.func.push({
                                key: sheetName,
                                action: () => {
                                    removeAllSpan(sheet, table);
                                    this.combineSameCell(sheet, table, spanKeys);
                                }
                            });
                        }
                        table.spanKeys = spanKeys;
                        // this.func.push({
                        //     key: sheetName,
                        //     action: () => {
                        //         const { rowCount: oldRowCount = 0, row: oldRow = 0 } = table.oldDataRange || {};
                        //         const startRow = oldRow + oldRowCount;
                        //         const { row, rowCount } = table.dataRange();
                        //         if (rowCount > oldRowCount) {
                        //             const height = sheet.getRowHeight(row);
                        //             for (let index = 0; index < rowCount - oldRowCount; index++) {
                        //                 sheet.setRowHeight((startRow === 0 ? row : startRow) + index, height);
                        //             }
                        //         }
                        //     }
                        // });
                        table.bindColumns(tableColumns);
                        table.bindingPath(table.bindingPath());
                    }
                });

                 if(!flag){
                     if (sheet.getColumnCount() < 50) {
                         sheet.setColumnCount(50);
                     }
                     if (sheet.getRowCount() < 200) {
                         sheet.setRowCount(200);
                     }
                     sheet.setDataSource(dataSource);
                 }
            });
        }

        this.calcAll();
        register(this.workbook.commandManager(), this);
        this.reEnterCell();
        this.workbook.resumePaint();
        afters.forEach(after => after());
        if (cuscode) {
            this.initCusCode(cuscode);
        }
        //this.changeSelectTypeValue();        
        this.workbook.options.newTabVisible = false;
        this.loading = false;

    }
    @action
    loadFormula = () => {
        if (this.customFuns) {
            return this.customFuns.map(obj => {
                const TempFunction = CustomFunction(obj);
                return () => {
                    const func = new TempFunction(
                        obj.name, 0, 0, { name: obj.name, description: obj.describes }
                    );
                    this.workbook.addCustomFunction(func);
                };
            });
        }
        return [];
    }

    initCusCode = (cuscode) => {
        //  const div = document.createElement('div');
        //div.className="edc-code-eara";
        // document.body.appendChild(div);
        // div.innerHTML = cuscode;
        // myDiv.id = "customCode";
        // document.writeln(cuscode);
        //  console.log( document.getElementById('customFunDiv'))
        //   if(document.getElementById('customFunDiv'))
        //  this.cuscode = cuscode;
        if (cuscode) {
            jQuery('<div class="edc-code-eara"/>').appendTo(jQuery(document.body)).html(cuscode);
        }

        //$("#customFunDiv").html(cuscode);
        // else setTimeout(() => {
        //     this.initCusCode(cuscode);
        // }, 50);
        //document.body.appendChild(eval(document.createTextNode(cuscode)));

        //myDiv.append(cuscode);
        // myDiv.appendChild(document.createTextNode(cuscode));
        // document.body.appendChild(myDiv);
    }

    combineSameCell = (sheet, table, spanKeys) => {
        const range = table.dataRange();
        this.combineRangeSameCell(sheet, range, [...spanKeys])
    }
    combineRangeSameCell = (sheet, range, spanKeys) => {
        const key = spanKeys.shift();
        if (key && range) {
            const { row, col, rowCount, colCount } = range;
            const currentCol = col + key.index;
            const v = sheet.getCell(row, currentCol).value();
            let oldValue = v ? JSON.stringify(v) : v;
            let rowCountToCombine = 1;
            let startRow = row;
            for (let index = 1; index < rowCount; index++) {
                const currentRow = row + index;
                const nv = sheet.getCell(currentRow, currentCol).value();
                const value = nv ? JSON.stringify(nv) : nv;
                if (oldValue === value && value && value != '[]') {
                    rowCountToCombine++;
                } else {
                    if (rowCountToCombine > 1) {
                        sheet.addSpan(startRow, currentCol, rowCountToCombine, 1);
                        this.combineRangeSameCell(sheet, { row: startRow, col, rowCount: rowCountToCombine, colCount }, [...spanKeys]);
                    }
                    startRow = currentRow;
                    rowCountToCombine = 1;
                    oldValue = value;
                }
            }
            if (rowCountToCombine > 1) {
                sheet.addSpan(startRow, currentCol, rowCountToCombine, 1);
                this.combineRangeSameCell(sheet, { row: startRow, col, rowCount: rowCountToCombine, colCount }, [...spanKeys]);
            }
        }
    }
    addDetail = () => {
        if (this.currentTable) {
            const { col, colCount } = this.currentTable.dataRange();
            this['edc.excelView.tableInsertBottomRow'](this.workbook, this.currentRow, col + colCount - 1);
        }
    }
    deleteDetail = () => {
        if (this.currentTable) {
            const { col, colCount } = this.currentTable.dataRange();
            this['edc.excelView.tableDeleteRow'](this.workbook, this.currentRow, col + colCount - 1);
        }
    }

    save = () => {

        if (!this.doBefore()) {
            return;

        }
        const source = this.dataSourceInstance.getSource();

        //dataTable改造
        ExcelAPI.saveData2({
            ...this.params,
            datas: JSON.stringify(this.updateJsonInstance),
            detailDataRow: JSON.stringify(this.detailDataRow),
            // json: JSON.stringify(this.workbook.toJSON(false)),
            deletedRows: JSON.stringify(this.deletedRows),
        }).then((params) => {
            message.success(getLabel('502231', '保存成功'));
            const urlParams = [];
            each(params, (value, key) => {
                if (typeof value === 'string' || typeof value === 'number') {
                    urlParams.push(`${key}=${value}`);
                }
            });
            window.location.reload();
            //window.weaHistory.push(`${route.excelView}?${urlParams.join('&')}`);
        });

        
        // ExcelAPI.saveData({
        //     ...this.params,
        //     datas: JSON.stringify(source),
        //     // json: JSON.stringify(this.workbook.toJSON(false)),
        //     deletedRows: JSON.stringify(this.deletedRows),
        // }).then((params) => {
        //     message.success(getLabel('502231', '保存成功'));
        //     const urlParams = [];
        //     each(params, (value, key) => {
        //         if (typeof value === 'string' || typeof value === 'number') {
        //             urlParams.push(`${key}=${value}`);
        //         }
        //     });
        //     window.weaHistory.push(`${route.excelView}?${urlParams.join('&')}`);
        // });
    }

    saveExcel = (exstore) => {

        console.log(exstore)
        const source = this.dataSourceInstance.getSource();

        //dataTable改造
        ExcelAPI.saveData2({
            ...this.params,
            datas: JSON.stringify(this.updateJsonInstance),
            detailDataRow: JSON.stringify(this.detailDataRow),
            // json: JSON.stringify(this.workbook.toJSON(false)),
            deletedRows: JSON.stringify(this.deletedRows),
        }).then((params) => {
            message.success(getLabel('502231', '保存成功'));
            // 刷新Excel展示页
            exstore.excelStore.reloadData();
        });


        // ExcelAPI.saveData({
        //     ...this.params,
        //     datas: JSON.stringify(source),
        //     // json: JSON.stringify(this.workbook.toJSON(false)),
        //     deletedRows: JSON.stringify(this.deletedRows),
        // }).then((params) => {
        //     message.success(getLabel('502231', '保存成功'));
        //     // 刷新Excel展示页
        //     exstore.excelStore.reloadData();
        // });
    }


    checkRequire = () => {
        // workbook不存在，意味着是自定义页面，不做必填校验
        if (!this.workbook) {
            return true;
        }
        const { sheets, ...json } = this.workbook.toJSON();
        const newSheets = {};
        let requireName;
        let requireLabel;
        const getSheet = ({ data, ...sheet }) => {
            const { dataTable, ...dataObj } = data;
            this.workbook.setActiveSheetIndex(sheet.index);
            const wksheet = this.workbook.getActiveSheet();
            const newDataTable = {};
            each(dataTable, (rowData, row) => {
                newDataTable[row] = {};
                if (requireName) {
                    return false;
                }
                each(rowData, (cellData, col) => {
                    const { style, ...restProps } = cellData;
                    if (typeof style === 'object' && style.cellType !== void 0 && style.cellType.viewAttr == 3) {
                        // 校验是否是必填
                        if (!wksheet.getCell(row, col).text()) {
                            if (!requireName) {
                                requireName = getCellName(Number(row), Number(col));
                                requireLabel = style.cellType.label || "";
                                this.requiredCellName = row + "@" + col;

                                const requireCell = wksheet.getCell(Number(row), Number(col));
                                if (!this.requiredCellBoderStyle[this.requiredCellName]) {
                                    this.requiredCellBoderStyle[this.requiredCellName] = [
                                        requireCell.borderTop(),
                                        requireCell.borderLeft(),
                                        requireCell.borderBottom(),
                                        requireCell.borderRight()];
                                }
                                this.workbook.suspendPaint();
                                const requiredBoderStyle = new GC.Spread.Sheets.LineBorder('red', GC.Spread.Sheets.LineStyle.medium);
                                requireCell.setBorder(requiredBoderStyle, { all: true });
                                this.workbook.resumePaint();
                            }

                            // 移转到必填项
                            //wksheet.showCell(row, col);

                            //wksheet.setActiveCell(row, col);
                            return false;
                        }

                    }
                })
            })
        }
        each(sheets, (sheet, sheetName) => {
            if (requireName) {
                return false;
            }
            newSheets[sheetName] = getSheet(sheet);
        });

        if (requireName) {
            message.error("[" + requireLabel + ":" + requireName + "]不能为空");

            return false;
        } else {
            this.requiredCellName = "";
            return true;
        }
    }

    doBefore = () => {
        if (typeof (checkCustomize) == "function") {
            return checkCustomize();

        }
        return true;
    }

    getStyleValue = (style, styleName) => {
        const obj = style[styleName];
        if (styleName.startsWith("border")) {
            return new GC.Spread.Sheets.LineBorder(obj.color, obj.style);
        } else {
            return obj;
        }
    }
    calcAll = (flag = true, sheetName) => {
        if (flag) {
            if (sheetName) {
                console.log("123")
                this.func.forEach(fun => {
                    if (fun.key === sheetName) {
                        //fun.action();
                    }
                });
                this.workbook.getSheetFromName(sheetName).tables.all().forEach(table => {
                   table.oldDataRange = { ...table.dataRange() };
                })
            } else {
                console.log("456")
                this.func.forEach(fun => {
                    //fun.action();
                });
                this.workbook.sheets.forEach(sheet => {
                   sheet.tables.all().forEach(table => {
                       table.oldDataRange = { ...table.dataRange() };
                   })
                })
            }
        }
        this.workbook.sheets.forEach(sheet => {
            sheet.recalcAll(true);
        });
    }

    insertDetailRow = (records, index) => {
        const newRecords = [];
        if (index === -1) {
            newRecords.push({ detail_index: 1 });
        }
        records.forEach((record, recordIndex) => {
            if (recordIndex < index) {
                newRecords.push(record);
            } else if (recordIndex === index) {
                newRecords.push(record);
                newRecords.push({ detail_index: recordIndex + 2 });
            } else {
                newRecords.push({ ...record, detail_index: recordIndex + 2 });
            }
        });
        return newRecords;
    }
    removeDetailRow = (records, index) => {
        const newRecords = [];
        if (index === -1) {
            newRecords.push({ detail_index: 1 });
        }
        let detailIndex = 1;
        records.forEach((record, recordIndex) => {
            if (recordIndex < index) {
                newRecords.push({ ...record, detail_index: detailIndex++ });
            } else if (recordIndex > index) {
                newRecords.push({ ...record, detail_index: detailIndex++ });
            }
        });
        return newRecords;
    }

    clickAnyWhere = (e) => {
        if (this.readonly) {
            return;
        }
        if (this.cantriggerClick) {
            const sheet = this.workbook.getActiveSheet();
            const activeCell = sheet.getCell(sheet.getActiveRowIndex(), sheet.getActiveColumnIndex());
            const celltype = activeCell.cellType();
            if (celltype) {
                if (typeof celltype.click === 'function') {
                    celltype.click(e, activeCell);
                }
            }
        }
    }

    mouseOverAnyWhere = (e) => {
        if (this.readonly) {
            return;
        }
        /* const sheet = this.workbook.getActiveSheet();
        const host = this.workbook.getHost();
        const offset = jQuery(host).offset();
        const topOffSet = offset.top;
        const leftOffSet = offset.left;
        const tables = sheet.tables.all();
        const size = tables.length;
        for (let index = 0; index < size; index++) {
            const table = tables[index];
            const { row, col, rowCount, colCount } = table.range();
            for (let index = 0; index < rowCount; index++) {
                const rect = this.getRangeRect(sheet, row + index, col, 1, colCount);
                const nextRect = sheet.getCellRect(row + index, col + colCount);
                const ex = e.clientX - leftOffSet;
                const ey = e.clientY - topOffSet;
                if (isNaN(nextRect.height) || isNaN(nextRect.width) || isNaN(rect.width) || isNaN(rect.height)) {
                    continue;
                }
                if (ex > rect.x && ey > nextRect.y && ex < rect.x + rect.width + nextRect.width && ey < nextRect.y + nextRect.height) {
                    this.showDetailBtns(rect.x + rect.width + 50, nextRect.y + topOffSet, nextRect.height, index !== 0);
                    this.currentTable = table;
                    this.currentRow = row + index;
                    return;
                } else {
                    this.hideDetailBtns();
                }
            }
        } */
    }
    getRangeRect = (sheet, row, col, rowCount, colCount) => {
        const { x, y } = sheet.getCellRect(row, col);
        const { x: x1, y: y1 } = sheet.getCellRect(row + rowCount, col + colCount);
        return {
            x, y,
            width: x1 - x,
            height: y1 - y
        };
    }
    showDetailBtns = (left, top, height, showDelete) => {
        if (this.cubeDetialBtns) {
            this.cubeDetialBtns.style.top = `${top}px`;
            this.cubeDetialBtns.style.display = 'block';
            this.cubeDetialBtns.style.height = `${height}px`;
            this.cubeDetialBtns.style.lineHeight = `${height}px`;
            this.cubeDetialBtns.style.left = `${left - 45}px`;
            this.showDetailDelete = showDelete;
        }
    }
    hideDetailBtns = () => {
        if (this.cubeDetialBtns) {
            this.cubeDetialBtns.style.display = 'none';
        }
    }
    @action
    reEnterCell = () => {
        const sheet = this.workbook.getActiveSheet();
        const sheetName = sheet.name();
        const col = sheet.getActiveColumnIndex();
        const row = sheet.getActiveRowIndex();
        this.enterCell({}, {
            col,
            row,
            sheet,
            sheetName
        });
    }

    tableToCell = () => {
        this.workbook.suspendPaint();
        const activeSheetIndex = this.workbook.getActiveSheetIndex();
        this.workbook.sheets.forEach(sheet => {
            this.workbook.setActiveSheet(sheet.name());
            this.activeSheetChange('', {
                newSheet: sheet
            });
            sheet.tables.all().forEach(table => {
                const { row, col, rowCount, colCount } = table.range();
                for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
                    for (let colIndex = 0; colIndex < colCount; colIndex++) {
                        const cell = sheet.getCell(row + rowIndex, col + colIndex);
                        const value = cell.text();
                        cell.cellType(new GC.Spread.Sheets.CellTypes.Base()).value(value);
                    }
                }

            })
        })
        this.workbook.setActiveSheetIndex(activeSheetIndex);
        this.workbook.resumePaint();
    }

    exportExcel = () => {
        const title = this.title;
        return new Promise(resolve => {
            const excelIO = new GC.Spread.Excel.IO();
            // this.needCheck = false;
            // this.tableToCell();
            // this.needCheck = true;
            const { sheets, ...json } = this.workbook.toJSON();
            const newSheets = {};
            const activeIndex = this.workbook.getActiveSheetIndex();
            const getSheet = ({ data, ...sheet }) => {
                const { dataTable, ...dataObj } = data;
                this.workbook.setActiveSheetIndex(sheet.index);
                const wksheet = this.workbook.getActiveSheet();
                const newDataTable = {};
                each(dataTable, (rowData, row) => {
                    newDataTable[row] = {};
                    each(rowData, (cellData, col) => {
                        const { style, ...restProps } = cellData;
                        const newStyle = style;
                        if (typeof style === 'object' && style.cellType !== void 0) {
                            delete newStyle.cellType;
                            delete newStyle.formatter;
                            restProps.value = wksheet.getCell(row, col).text();
                        }
                        newDataTable[row][col] = {
                            ...restProps,
                            style: newStyle
                        }
                    })
                })
                return {
                    ...sheet,
                    data: {
                        ...dataObj,
                        dataTable: newDataTable
                    }
                }
            }
            each(sheets, (sheet, sheetName) => {
                newSheets[sheetName] = getSheet(sheet);
            });
            const newJson = {
                ...json,
                newTabVisible: true,
                sheets: newSheets
            }
            this.workbook.setActiveSheetIndex(activeIndex);
            excelIO.save(newJson, (blob) => {
                saveAs(blob, `${title}.xlsx`);
                // this.init(this.params);
                resolve();
            }, function (e) {
                if (!!(window.console && window.console.log)) {
                    window.console.log(e);
                }
                // this.init(this.params);
                resolve();
            });
        })
    }

    // exportExcelTemplate = (title = this.title) => {
    //     //API.template(this.params).then(this.downTemplate)
    //     return new Promise(resolve => {
    //         const excelIO = new GC.Spread.Excel.IO();
    //         this.tableToCell();
    //         console.log(this.workbook.toJSON());
    //         excelIO.save(this.workbook.toJSON(), (blob) => {
    //             saveAs(blob, `${this.title}.xlsx`);
    //             //this.init(this.params);
    //             resolve();
    //         }, function (e) {
    //             if (!!(window.console && window.console.log)) {
    //                 window.console.log(e);
    //             }
    //             resolve();
    //         });
    //     });
    // }

    downTemplate = (template) => {
        let fileName = template.fileName || template.name;
        if (fileName.substr(-5, 5) !== '.xlsx') {
            fileName += '.xlsx';
        }
        return new Promise(resolve => {
            const excelIO = new GC.Spread.Excel.IO();
            excelIO.save(template.json, (blob) => {
                saveAs(blob, fileName);
                resolve();
            }, function (e) {
                if (!!(window.console && window.console.log)) {
                    window.console.log(e);
                }
            });
            resolve();
        });
    }

    getShowListDatas = (oldFields, newFields) => {
        return new Promise(resolve => {
            const [file] = newFields;
            if (file) {
                const fileInstance = file.getNative();
                this.loadFile(fileInstance, fileInstance.name.replace('.xlsx', ''));
                this.setVisible(false);
            }
            resolve();
        }, function (e) {
            if (!!(window.console && window.console.log)) {
                window.console.log(e);
            }
        });
    }

    loadFile(file, name) {

        const excelIO = new GC.Spread.Excel.IO();
        excelIO.open(
            file,
            json => {
                this.showLoadPage({
                    json: json,
                    labels: {},
                    fieldName: {},
                    name
                });
                //this.templateJSON = json;
            },
            (error) => {
                message.error(error);
                this.loading = false;
            }
        );
    }

    showLoadPage = (page) => {

        const json = page.json;
        const sheets = json.sheets;

        ExcelAPI.uploadData({
            dataJson: JSON.stringify(sheets),
            sheetsJson: JSON.stringify(this.workbook.toJSON(false))
        }).then(this.bindDatasource);
        return;
        // let cellType;
        // // 明细表
        // let mxTable;
        // // 明细区域
        // let mxRange;
        // let mxRow;
        // let mxCol;
        // let mxColumn;
        // let mxBindPath;
        // let mainPath;
        // this.workbook.suspendPaint();
        // each(sheets, (sheet, name) => {
        //     const { data } = sheet;
        //     const { dataTable } = data;
        //     sheet = window.workbookInstance.getSheetFromName(name);
        //     if (sheet) {
        //         if (dataTable) {
        //             each(dataTable, (x, row) => {
        //                 each(x, (y, col) => {
        //                     cellType = sheet.getCell(row, col).cellType();
        //                     // 是否为有效区域
        //                     if (cellType) {
        //                         mxTable = sheet.tables.find(row, col);
        //                         // 判断是否为明细表
        //                         if (mxTable) {
        //                             mxRange = mxTable.dataRange();
        //                             mxRow = row - mxRange.row;
        //                             mxCol = col - mxRange.col;
        //                             mxColumn = mxTable.getColumnDataField(mxCol);
        //                             mxBindPath = mxTable.bindingPath();
        //                             if (y["value"]) {
        //                                 this.dataSourceInstance.getValue(mxBindPath)[mxRow][mxColumn] = this.valueCheck(cellType, y["value"]);
        //                             } else {
        //                                 this.dataSourceInstance.getValue(mxBindPath)[mxRow][mxColumn] = "";
        //                             }

        //                         } else {
        //                             mainPath = sheet.getCell(row, col).bindingPath();

        //                             if (mainPath) {
        //                                 if (y["value"]) {
        //                                     this.dataSourceInstance.setValue(mainPath, this.valueCheck(cellType, y["value"]));
        //                                 } else {
        //                                     this.dataSourceInstance.setValue(mainPath, "");
        //                                 }

        //                             }
        //                         }

        //                     }

        //                 });
        //             });
        //         }
        //     }


        // });

        this.workbook.resumePaint();

    }
    @action toggle = () => {
        this.autoSaveDatasvisible = !this.autoSaveDatasvisible;
    }

    bindDatasource = (ds) => {
        const dataSource = window.dataSourceInstance = this.dataSourceInstance = new GC.Spread.Sheets.Bindings.CellBindingSource(ds);
        this.workbook.suspendPaint();
        this.workbook.sheets.forEach(sheet => {

            sheet.setDataSource(dataSource);
            this.calcAll();
        });
        this.workbook.resumePaint();
    }

    valueCheck = (cellType, newValue) => {
        if (cellType instanceof WeaInputCellType) {
            const { fieldType: [htmlType, type, dbtype] } = cellType;
            if (type === 'text') {
                const length = parseInt(dbtype);
                if (this.GetLength(`${newValue}`) > length) {

                    message.error(`${getLabel(502997, '长度不能超过') + length}`);
                    return "";
                } else {
                    return newValue;
                }

            } else if (type === 'int') {
                const realValue = parseInt(newValue);
                if (isNaN(realValue)) {
                    message.error(getLabel(502998, `请输入整数`));
                    return "";
                } else {
                    return realValue;
                }

            } else if (type === 'float') {
                const realValue = parseFloat(newValue);
                const length = parseInt(dbtype);
                if (isNaN(realValue)) {
                    message.error(getLabel(502999, `请输入浮点数`));
                    return "";
                } else {
                    return realValue.toFixed(length);
                }

            }
        }
    }
    GetLength = (str) => {
        ///<summary>获得字符串实际长度，中文2，英文1</summary>
        ///<param name="str">要获得长度的字符串</param>
        var realLength = 0, len = str.length, charCode = -1;
        for (var i = 0; i < len; i++) {
            charCode = str.charCodeAt(i);
            if (charCode >= 0 && charCode <= 128)
                realLength += 1;
            else
                realLength += 2;
        }
        return realLength;
    };
    @action setVisible = (bool) => {
        this.visible = bool;
    }

    @observable rowIndex = 0;
    @action topRowChanged = (e, info) => {//dataTable改造
        const { newTopRow, oldTopRow } = info;
        //每翻100行(上下翻)数据,访问接口重新获取数据
        const f1 = newTopRow > oldTopRow && Math.floor((newTopRow - this.rowIndex) / 100) > 0;
        const f2 = newTopRow < oldTopRow && Math.floor((this.rowIndex - newTopRow) / 100) > 0;
        if (f1 || f2) {
            this.rowIndex = newTopRow;
             API.excel2({ ...this.params, topRow: newTopRow + 1, detailDataRow: JSON.stringify(this.detailDataRow) }).then((result) => {
                 this.showPage(result.page,true);
                 this.rowIndex = newTopRow;
                 this.workbook.getActiveSheet().showRow(newTopRow);//选中当前行
             })
        }
    }
}